/*
 * Copyright (c) 2009 Enio Perpetuo
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * 		http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 *  
 */
package co.za.gvi.handler;

import java.io.InputStream;
import java.io.OutputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.xml.sax.SAXException;

import co.za.gvi.bind.GviSmsMessageType;
import co.za.gvi.bind.ObjectFactory;

/**
 * The <code>DispatchMessageHandler</code> class is responsible for governing the process of 
 * serializing and deserializing XML data.
 * 
 * @author Enio Perpetuo
 */
public class DispatchMessageHandler {
	
	private static Class<? extends ObjectFactory> objectFactory = ObjectFactory.class;

	/**
	 * Constructor
	 */
	public DispatchMessageHandler() {
		// Empty constructor
	}
	
	/**
	 * This method is used to set a custom <code>ObjectFactory</code>
	 * 
	 * @param objectFactory The custom <code>ObjectFactory</code>
	 */
	public static void registerObjectFactory(Class<? extends ObjectFactory> objectFactory) {
		DispatchMessageHandler.objectFactory = objectFactory;
	}
	
	/**
	 * Marshal the content tree rooted at a GviSmsMessageType into an output stream.
	 * 
	 * @param message The message
	 * @param outputStream The output stream where to write the XML content 
	 * 
	 * @throws JAXBException if any unexpected problem occurs during the marshaling
	 */
	public void marshal(JAXBElement<GviSmsMessageType> message, OutputStream outputStream) 
	throws JAXBException {
		JAXBContext jc = JAXBContext.newInstance(DispatchMessageHandler.objectFactory);
		Marshaller m = jc.createMarshaller();
		m.marshal(message, outputStream);
	}

	/**
	 * Unmarshal an XML input stream into a Java content tree
	 * 
	 * @param is The XML input stream
	 * @return The JAXB representation of a GviSmsMessageType
	 * 
	 * @throws JAXBException if an error was encountered while creating the Unmarshaller object
	 * @throws SAXException if a SAX error occurs during parsing
	 */
	@SuppressWarnings("unchecked")
	public JAXBElement<GviSmsMessageType> unmarshal(InputStream is) 
	throws JAXBException, SAXException {

		JAXBContext jc = JAXBContext.newInstance(DispatchMessageHandler.objectFactory);
		Unmarshaller um = jc.createUnmarshaller();
		
		// Validate
		//SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		//um.setSchema(sf.newSchema(new SAXSource(new InputSource(is))));

		return (JAXBElement<GviSmsMessageType>) um.unmarshal(is);
	}
}
